<template>
  <div class="callreport" v-loading="loading">
    <div class="top">
      <div class="search">
        <div class="contition">
          <div class="wrap_time">
            <date-time type="other_half_hour" :query="query" :isTimePeriod="true" ref="timeChild" :isOther="true">
            </date-time>
            <el-button type="primary" class="primary_btn fr find" v-on:click.stop="search">{{ $t('public.search2') }}
            </el-button>
            <div class="clear"></div>
          </div>
        </div>
      </div>
      <affix :label="$t('report.callOutSurvey')"></affix>
      <div class="situation">
        <el-row>
          <el-col :span="6" v-for="(item, index) in situation" :key="index">
            <span class="sum_name">{{ item.name }}</span>
            <span class="sit_num">{{ item.value }}</span>
          </el-col>
        </el-row>
      </div>
      <affix :label="$t('report.relaycalloutRe')"></affix>
    </div>
    <div :id="id">
      <el-row class="ichars">
        <highcharts :options="options24out"></highcharts>
        <div class="notes">
          <span class="light">{{ $t('report.hicharsNotes') }}: <span></span>{{ $t('report.hicharsLight') }}</span>
          <span class="dark"><span></span>{{ $t('report.hicharsDark') }}</span>
        </div>
      </el-row>
      <div class="tab">
        <div class="export">
          <el-button class="primary_btn fr formal" v-if="configFormula" @click="$refs.formulaEditorDialog.open()">
            {{ $t('report.formalTitle') }}</el-button>
          <el-button class="primary_btn fr" v-on:click.stop="config" v-if="!configHeaderBool">
            {{ $t('report.setHeaderConfig') }}</el-button>

          <!-- <el-button class="primary_btn fr report_excel_btn"
            v-if="$store.getters.exportFromEnd"
            v-on:click.stop="exportExcel"
          >{{$t('report.exportXls')+($store.state.xlsxExportMode==='Both'?'(旧)':'')}}</el-button> -->

          <el-button class="primary_btn fr report_excel_btn" v-on:click.stop="exportXlsx">{{ $t('report.exportXls') }}
          </el-button>

          <el-button class="primary_btn fr pdf" v-on:click.stop="exportPdf">{{ $t('report.exportPDF') }}</el-button>
          <el-select @change="search" v-if="$refs.timeChild && $refs.timeChild.form.timeType === 'day'" class="fr"
            size="mini" v-model="query.granularity" style="height:30px;width:120px;">
                        
            <el-option :label="$t('report.oneHourTrend')" value="1h" />
                        
            <el-option :label="$t('report.halfHourTrend')" value="0.5h" />
                      
          </el-select>
        </div>
        <div class="deploy">
          <el-collapse accordion>
            <el-collapse-item>
              <template slot="title">
                <span class="fl explain">{{ $t('report.toggleInstructe') }}</span>
              </template>
              <div>
                {{ $t('report.callOutNum') }}<br>
                {{ $t('report.callOutSucNum') }}<br>
                {{ $t('report.callOutRingNotAnsNum') }}<br>
                {{ $t('report.callOutFailNum') }}<br>
                {{ $t('report.callOutSucRate') }}<br>
                {{ $t('report.callOutAllTime') }}<br>
                {{ $t('report.callOutAverTime') }}
                <p class="custom_alg">{{ $t('report.ziDingYi') }}：</p>
                <p v-for="(item, index) in formulas" :key="item.name">
                  {{ index + 8 }}.{{ item.formulaInstr }}
                </p>
              </div>
            </el-collapse-item>
          </el-collapse>
        </div>
        <report-table :data="serveNumData" :sum="sum" :config="[...headOptions.Config, ...formulasConfig]">
        </report-table>
      </div>
    </div>
    <el-dialog :close-on-click-modal="false" modal-append-to-body lock-scroll top="10%"
      :title="$t('report.reportExportHelp')" :visible.sync="dialogVisible" width="30%">
      <span>{{ $t('report.reportExportTipTitle') }}</span>
      <span slot="footer" class="dialog-footer">
        <el-button class="primary_btn" @click="dialogVisible = false">{{ $t('public.cancel') }}</el-button>
        <el-button class="primary_btn" type="primary" @click="confirm">{{ $t('public.confirm') }}</el-button>
      </span>
    </el-dialog>
    <header-option v-show="isShow" :show="isShow" :option="headOptionsShow" type="call_report_callout_time"
      v-on:close="close" :headCustom="formulasConfig"></header-option>
    <!-- 自定义公式组件 -->
    <FormulaEditorDialog ref="formulaEditorDialog" :headOptionsConfig="headOptions.Config"
      @closeFormulaDialog="closeFormulaDialog" reportName="呼出时间趋势报表" :reportType="id" />
  </div>
</template>
<script>
import affix from '../../../ui-modules/affix/Affix.vue'
import dateTime from '../base/datetime.vue'
import { exportReportPdf, checkTime, searchTime, colorConfigArr, headOptionsToXlsxHeaders, mixData } from '@/utils/reportUtils.js'
import headerOption from '../base/headerOption.vue'
import { getCache, deepClone, getCallTimeLength, optionTimeTypeCheck, isHasFunc } from '@/utils/m7Utils.js'
import reportTable from '../base/reportTable.vue'
import * as XlsxUtil from 'src/utils/XlsxUtil.umd.js'
import { sortBy } from 'lodash'
import FormulaEditorDialog from '../base/FormulaEditorDialog.vue'

export default {
  name: '',
  data() {
    return {
      configFormula: true, // 自定义公式的权限
      situation: [], // 渲染概况的数据
      loading: false, // 查询数据展示加载的弹窗开关
      id: 'call_report_callout_time', // 查询数据的id
      query: { // 时间条件绑定的对象
        granularity: '0.5h', // 时间趋势
      },
      isShow: false, // 配置表头弹窗是否展示的开关
      headOptions: { // 表头相关数据
        Config: []
      },
      resData: [], // 返回数组暂存
      formulas: [], // 公式数据
      dialogVisible: false, // 导出pdf弹窗绑定值
      serveNumData: [], // 表格数据绑定值
      headOptionsShow: {}, // 配置表头用的表头数据
      sum: [ // 合计数据
        { time: this.$t('report.total') }
      ],
      options24out: {
        chart: {
          type: '',
          animation: false
        },
        colors: colorConfigArr,
        xAxis: {
          categories: []
        },
        yAxis: {
          gridLineColor: '#e6e6e6',
          allowDecimals: false,
          title: {
            text: ''
          }
        },
        title: {
          text: this.$t('report.callOutTime')
        },
        legend: {
          align: 'center',
          verticalAlign: 'top',
          x: 0,
          y: 20
        },
        tooltip: {
          shared: true
        },
        plotOptions: {
          column: {
            stacking: 'normal'
          },
          series: { animation: false }
        },
        credits: { enabled: false },
        series: [],
      }
    }
  },
  methods: {
    // 自定义公式弹窗关闭外抛事件
    closeFormulaDialog() {
      this.isSearch = false
      this.$store.dispatch('queryFetchFormula', { type: this.id }).then((resp) => {
        if (resp.success) {
          this.formulas = resp.data.Formulas
        }
      })
    },
    // 查询条件抽出 方便导出和查询用
    getSearchQueryData() {
      // 完善查询条件
      let data = {
        reportType: 'call_report_callout_time',
        account: this.$store.state.session.user.account
      }
      let isWeek = this.$refs.timeChild.form.timeType
      let myQuery = deepClone(this.query)
      if (isWeek === 'week') {
        myQuery.timeType = 'other'
        let message = checkTime(myQuery.StartTime, myQuery.EndTime, false, true)
        if (message !== true) {
          this.$message.error(this.$t(message))
          return
        }
      } else if (myQuery.timeType === 'other_half_hour') {
        // 校验类型与时间
        let message = checkTime(myQuery.StartTime, myQuery.EndTime, false, false)
        if (message !== true) {
          this.$message.error(this.$t(message))
          return
        }
      }
      // 时间插件返回的是小写的timeType转大写的
      myQuery.TimeType = myQuery.timeType
      delete myQuery.timeType
      data['query'] = myQuery
      return data
    },
    // 获取合计和处理data
    getServeNumDataAndSum(myQuery) {
      let sum = { ReportTime: this.$t('report.total') }
      let tempData = deepClone(mixData(this.resData, this.formulas))
      for (let i in tempData) {
        let item = tempData[i]
        // 月报年报返回字段不一样处理
        if (myQuery.TimeType === 'year') {
          item.ReportTime = item.MonthID
          delete item.MonthID
        } else if (myQuery.TimeType === 'month') {
          item.ReportTime = item.DayID
          delete item.DayID
        } else if ((myQuery.TimeType === 'other_half_hour') && myQuery.timePeriod) {
          //    查询方式为  自定义 或  日报  并且 定时间段统计  则更换 时间 渲染的字段
          item.ReportTime = item.DayID
          delete item.DayID
        } else if (myQuery.TimeType === 'other') { // 周报查询按天展示
          item.ReportTime = item.DayID
        }
        // 计算合计
        for (let j in item) {
          if (sum[j] === undefined) {
            sum[j] = 0
          }
          if (j !== 'ReportTime') {
            sum[j] += item[j]
          }
        }
        this.headOptions.Config.forEach((option, index) => {
          if (option.name.indexOf('Rate') > -1 && option.displayname.indexOf('率') > -1) {
              item[option.name] = `${item[option.name]}%`
          }
          if (option.timeType && option.timeType === 'hhmmss') {
            item[option.name] = getCallTimeLength(item[option.name])
          } else if (option.timeType && option.timeType === 'second') {
            item[option.name] = Math.round(item[option.name]) + 's'
          }
        })
      }

      sum = mixData([sum], this.formulas)
      // 处理table合计中需要计算的列
      sum[0].DealingRate = sum[0].AccessCount === 0 ? '0' : Math.round((sum[0].DealingCount / sum[0].AccessCount) * 100) + '%'
      sum[0].CallTimeLengthAvg = sum[0].CallTimeLength / sum[0].DealingCount || 0

      this.headOptions.Config.forEach((option, index) => {
        if (option.timeType && option.timeType === 'hhmmss') {
          sum[0][option.name] = getCallTimeLength(sum[0][option.name])
        } else if (option.timeType && option.timeType === 'second') {
          sum[0][option.name] = Math.round(sum[0][option.name]) + 's'
        } 
      })
      return {
        sum: sum,
        dataDeal: sortBy(tempData, 'ReportTime'),
      }
    },

    // 查询的方法
    search() {
      var data = this.getSearchQueryData()
      if (!data) {
        return
      }

      var myQuery = data.query
      this.loading = true
      this.$store.dispatch('queryCallCalloutTimeReport', data).then((res) => {
        if (this.$store.state.report.customExportData) {
          res = JSON.parse(this.$store.state.report.customExportData)
        }
        if (!res.success) {
          this.loading = false
          return
        }
        this.$store.dispatch('queryFetchFormula', { type: this.id }).then((resp) => {
          if (resp.success) {
            this.formulas = resp.data.Formulas
            this.resData = res.data
            //  图表标题 加入 定时段的 时间
            let highchartsTitle = ''
            if (myQuery.timePeriod) {
              let timePeriodStartStr = myQuery.timePeriodStart || '00:00'
              let timePeriodEndStr = myQuery.timePeriodEnd || '23:59'
              highchartsTitle = '(' + timePeriodStartStr + '~' + timePeriodEndStr + ')'
            }
            this.options24out.title.text = this.$t('report.callOutTime') + highchartsTitle
            this.headOptions = optionTimeTypeCheck(res.tableHeader)
            let tempData = deepClone(mixData(this.resData, this.formulas))
            this.situation = []
            // 如果数据为空 初始数据图表 终止代码执行
            if (!tempData || tempData.length === 0) {
              // 无数据渲染概况
              let Config = this.headOptions.Config
              this.options24out.series = []
              for (var i = 0; i < Config.length; i++) {
                if (['ReportTime', 'CallTimeLength', 'CallTimeLengthAvg', 'DealingRate'].indexOf(Config[i].name) < 0) {
                  this.situation.push({
                    name: Config[i].displayname,
                    value: 0
                  })
                  this.options24out.series.push({
                    name: Config[i].displayname,
                    data: []
                  })
                }
              }
              this.serveNumData = []
              this.loading = false
              return
            }
            let { sum, dataDeal } = this.getServeNumDataAndSum(myQuery)
            this.sum = sum
            // 数据排序
            this.serveNumData = sortBy(dataDeal, 'ReportTime')
            // 渲染icharts图表
            let series4high = {}
            this.options24out.xAxis.categories = []
            for (let i in this.serveNumData) {
              let item = this.serveNumData[i]
              this.options24out.xAxis.categories.push(item.ReportTime)
              for (let j in item) {
                if (series4high[j] === undefined) {
                  series4high[j] = []
                }
                // 判断提示是否显示该字段
                if (['ReportTime', 'CallTimeLength', 'CallTimeLengthAvg', 'DealingRate'].indexOf(j) < 0) {
                  series4high[j].push(item[j])
                } else {
                  delete series4high[j]
                }
              }
            }
            this.options24out.series = []
            // 循环表头将符合条件得加入到概况和图表数据
            for (let i in res.tableHeader.Config) {
              let item = res.tableHeader.Config[i]
              if (['ReportTime', 'CallTimeLength', 'CallTimeLengthAvg', 'DealingRate'].indexOf(item.name) < 0) {
                // 渲染概况
                this.situation.push({
                  name: item.displayname,
                  value: this.sum[0][item.name]
                })
                // 渲染图表数据
                this.options24out.series.push({
                  name: item.displayname,
                  data: series4high[item.name]
                })
              }
            }
            this.loading = false
          }
        })
      })
    },
    // 导出表格数据执行的方法(前端)
    exportXlsx() {
      var data = this.getSearchQueryData()
      if (!data) {
        return
      }

      var myQuery = data.query
      this.loading = true

      this.$store.dispatch('queryCallCalloutTimeReport', data).then((res) => {
        if (this.$store.state.report.customExportData) {
          res = JSON.parse(this.$store.state.report.customExportData)
        }
        if (!res.success) {
          this.loading = false
          return
        }
        this.loading = false
        var headOptions = optionTimeTypeCheck(res.tableHeader)
        // let tempData = deepClone(res.data)
        let { sum, dataDeal } = this.getServeNumDataAndSum(myQuery)
        // 排序之后合并合计数组
        var tableData = sortBy(dataDeal, 'ReportTime').concat(sum)

        var headers = headOptionsToXlsxHeaders([...headOptions.Config, ...this.formulasConfig])

        var dh = XlsxUtil.getDownloadHelper(headers, tableData)
        var timeStamp = XlsxUtil.dateFormat(new Date(), 'yyyy-MM-dd hh-mm-ss')
        dh.download(this.$t('report.calloutReport') + timeStamp)
      })
    },
    // 打开确认是否导出pdf弹窗
    exportPdf() {
      this.dialogVisible = true
    },
    // 确认导出pdf执行的方法
    confirm() {
      this.dialogVisible = false
      exportReportPdf({ title: this.$t('report.calloutReport') + searchTime(this.query), id: this.id })
    },
    // 导出表格数据执行的方法(后端)
    exportExcel() {
      let myQuery = deepClone(this.query)
      let isWeek = this.$refs.timeChild.form.timeType
      if (isWeek === 'week') {
        myQuery.timeType = 'other'
        let message = checkTime(myQuery.StartTime, myQuery.EndTime, false, true)
        if (message !== true) {
          this.$message.error(this.$t(message))
          return
        }
      } else if (myQuery.timeType === 'other_half_hour') {
        // 校验类型与时间
        let message = checkTime(myQuery.StartTime, myQuery.EndTime, false, false)
        if (message !== true) {
          this.$message.error(this.$t(message))
          return
        }
      }
      // 时间插件返回的是小写的timeType转大写的
      myQuery.TimeType = myQuery.timeType
      delete myQuery.timeType
      myQuery.reportType = 'call_report_callout_time'
      myQuery.accountId = this.$store.state.session.user.account
      myQuery.type = 'ReportDialoutExport'
      myQuery.user = this.$store.state.session.user._id
      let data = {
        Method: 'exportDialoutTime',
        Query: myQuery
      }
      this.$store.dispatch('exportCallCalloutTimeReport', data).then(() => {
      })
    },
    // 关闭配置表头弹窗,如果点击保存则查询重新渲染数据
    close(data) {
      this.isShow = false
      if (data === 'save') {
        this.search()
      }
    },
    // 获取表头数据
    config() {
      this.$store.dispatch('getReportTableHeader', 'call_report_callout_time').then((res) => {
        this.headOptionsShow = optionTimeTypeCheck(res)
        this.isShow = !this.isShow
      })
    },

  },
  components: {
    affix,
    dateTime,
    headerOption,
    reportTable,
    FormulaEditorDialog
  },
  computed: {
    // 判断是否展示配置表头
    configHeaderBool() {
      return this.$store.state.report.setConfigHeaderBool
    },
    // 自定义表头
    formulasConfig() {
      return this.formulas.map((d, i) => {
        return {
          displayname: d.displayname,
          name: d.name,
          order: d.order,
          show: d.show,
          timeType: 'none',
          digits: d.digits,
          type: d.type
        }
      })
    }
  },
  watch: {
    // 监测自定义公式变化 更新数据
    formulas(cur, old) {
      if (this.isSearch) {
        return
      }
      if (!this.serveNumData || this.serveNumData.length === 0) {
        return
      }
      var queryData = this.getSearchQueryData()
      if (!queryData) {
        return
      }
      var myQuery = queryData.query
      let { sum, dataDeal } = this.getServeNumDataAndSum(myQuery)
      this.sum = sum
      this.serveNumData = dataDeal
    }
  },
  beforeMount() {
    if (isHasFunc('func_forbid_config_formula', this.$store.state.session.user)) {
      this.configFormula = false // 没有自定义公式的配置权限
    }
    this.$store.dispatch('getCache', { type: 'serviceNo' }).then(() => {
      this.serviceNos = getCache('serviceNo')
      this.search()
    })
  }
}
</script>
<style lang="stylus" scoped>
  @import "../../../../assets/common.styl"
  .tip
    cursor pointer
    display inline-block
    border 1px solid #459ae9
    text-align center
    line-height 16px
    border-radius 50%
    margin 0 0 0 6px
    width 16px
  .formal
    margin-left 10px
  .queue
    .skill
      .el-select
        width 400px
</style>
